// utils/index.ts
// 工具函数库

/**
 * 时间工具类
 */
class TimeUtils {
  /**
   * 格式化时间
   */
  static formatTime(date, format = 'YYYY-MM-DD HH:mm:ss') {
    const d = new Date(date)
    const year = d.getFullYear()
    const month = String(d.getMonth() + 1).padStart(2, '0')
    const day = String(d.getDate()).padStart(2, '0')
    const hour = String(d.getHours()).padStart(2, '0')
    const minute = String(d.getMinutes()).padStart(2, '0')
    const second = String(d.getSeconds()).padStart(2, '0')
    
    return format
      .replace('YYYY', String(year))
      .replace('MM', month)
      .replace('DD', day)
      .replace('HH', hour)
      .replace('mm', minute)
      .replace('ss', second)
  }
  
  /**
   * 获取相对时间
   */
  static getRelativeTime(date) {
    const now = new Date()
    const target = new Date(date)
    const diff = now.getTime() - target.getTime()
    
    const minute = 60 * 1000
    const hour = 60 * minute
    const day = 24 * hour
    const week = 7 * day
    const month = 30 * day
    const year = 365 * day
    
    if (diff < minute) {
      return '刚刚'
    } else if (diff < hour) {
      return `${Math.floor(diff / minute)}分钟前`
    } else if (diff < day) {
      return `${Math.floor(diff / hour)}小时前`
    } else if (diff < week) {
      return `${Math.floor(diff / day)}天前`
    } else if (diff < month) {
      return `${Math.floor(diff / week)}周前`
    } else if (diff < year) {
      return `${Math.floor(diff / month)}个月前`
    } else {
      return `${Math.floor(diff / year)}年前`
    }
  }
  
  /**
   * 获取时间段描述
   */
  static getTimeOfDay() {
    const hour = new Date().getHours()
    
    if (hour >= 5 && hour < 12) {
      return '早晨'
    } else if (hour >= 12 && hour < 14) {
      return '中午'
    } else if (hour >= 14 && hour < 18) {
      return '下午'
    } else if (hour >= 18 && hour < 22) {
      return '晚上'
    } else {
      return '深夜'
    }
  }
  
  /**
   * 判断是否为今天
   */
  static isToday(date) {
    const today = new Date()
    const target = new Date(date)
    
    return today.getFullYear() === target.getFullYear() &&
           today.getMonth() === target.getMonth() &&
           today.getDate() === target.getDate()
  }
  
  /**
   * 获取星期几
   */
  static getWeekday(date) {
    const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
    const d = new Date(date)
    return weekdays[d.getDay()]
  }
}

/**
 * 字符串工具类
 */
class StringUtils {
  /**
   * 生成随机字符串
   */
  static randomString(length = 8, chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') {
    let result = ''
    for (let i = 0; i < length; i++) {
      result += chars.charAt(Math.floor(Math.random() * chars.length))
    }
    return result
  }
  
  /**
   * 生成UUID
   */
  static generateUUID() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
      const r = Math.random() * 16 | 0
      const v = c === 'x' ? r : (r & 0x3 | 0x8)
      return v.toString(16)
    })
  }
  
  /**
   * 截断字符串
   */
  static truncate(str, length, suffix = '...') {
    if (str.length <= length) {
      return str
    }
    return str.substring(0, length - suffix.length) + suffix
  }
  
  /**
   * 首字母大写
   */
  static capitalize(str) {
    return str.charAt(0).toUpperCase() + str.slice(1)
  }
  
  /**
   * 驼峰转下划线
   */
  static camelToSnake(str) {
    return str.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`)
  }
  
  /**
   * 下划线转驼峰
   */
  static snakeToCamel(str) {
    return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase())
  }
  
  /**
   * 移除HTML标签
   */
  static stripHtml(str) {
    return str.replace(/<[^>]*>/g, '')
  }
  
  /**
   * 转义HTML
   */
  static escapeHtml(str) {
    const map = {
      '&': '&amp;',
      '<': '&lt;',
      '>': '&gt;',
      '"': '&quot;',
      "'": '&#39;'
    }
    return str.replace(/[&<>"']/g, m => map[m])
  }
}

/**
 * 数字工具类
 */
class NumberUtils {
  /**
   * 格式化数字
   */
  static formatNumber(num, decimals = 2) {
    return num.toFixed(decimals)
  }
  
  /**
   * 格式化大数字
   */
  static formatLargeNumber(num) {
    if (num >= 1000000000) {
      return (num / 1000000000).toFixed(1) + 'B'
    } else if (num >= 1000000) {
      return (num / 1000000).toFixed(1) + 'M'
    } else if (num >= 1000) {
      return (num / 1000).toFixed(1) + 'K'
    }
    return num.toString()
  }
  
  /**
   * 生成随机数
   */
  static random(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min
  }
  
  /**
   * 限制数字范围
   */
  static clamp(num, min, max) {
    return Math.min(Math.max(num, min), max)
  }
  
  /**
   * 线性插值
   */
  static lerp(start, end, factor) {
    return start + (end - start) * factor
  }
  
  /**
   * 角度转弧度
   */
  static degToRad(degrees) {
    return degrees * (Math.PI / 180)
  }
  
  /**
   * 弧度转角度
   */
  static radToDeg(radians) {
    return radians * (180 / Math.PI)
  }
}

/**
 * 颜色工具类
 */
class ColorUtils {
  /**
   * 十六进制转RGB
   */
  static hexToRgb(hex) {
    const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
    return result ? {
      r: parseInt(result[1], 16),
      g: parseInt(result[2], 16),
      b: parseInt(result[3], 16)
    } : null
  }
  
  /**
   * RGB转十六进制
   */
  static rgbToHex(r, g, b) {
    return '#' + [r, g, b].map(x => {
      const hex = x.toString(16)
      return hex.length === 1 ? '0' + hex : hex
    }).join('')
  }
  
  /**
   * HSL转RGB
   */
  static hslToRgb(h, s, l) {
    h /= 360
    s /= 100
    l /= 100
    
    const hue2rgb = (p, q, t) => {
      if (t < 0) t += 1
      if (t > 1) t -= 1
      if (t < 1/6) return p + (q - p) * 6 * t
      if (t < 1/2) return q
      if (t < 2/3) return p + (q - p) * (2/3 - t) * 6
      return p
    }
    
    let r, g, b
    
    if (s === 0) {
      r = g = b = l
    } else {
      const q = l < 0.5 ? l * (1 + s) : l + s - l * s
      const p = 2 * l - q
      r = hue2rgb(p, q, h + 1/3)
      g = hue2rgb(p, q, h)
      b = hue2rgb(p, q, h - 1/3)
    }
    
    return {
      r: Math.round(r * 255),
      g: Math.round(g * 255),
      b: Math.round(b * 255)
    }
  }
  
  /**
   * 生成随机颜色
   */
  static randomColor() {
    return '#' + Math.floor(Math.random() * 16777215).toString(16).padStart(6, '0')
  }
  
  /**
   * 获取颜色亮度
   */
  static getBrightness(hex) {
    const rgb = this.hexToRgb(hex)
    if (!rgb) return 0
    return (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000
  }
  
  /**
   * 判断颜色是否为深色
   */
  static isDark(hex) {
    return this.getBrightness(hex) < 128
  }
}

/**
 * 存储工具类
 */
class StorageUtils {
  /**
   * 设置本地存储
   */
  static setItem(key, value) {
    try {
      wx.setStorageSync(key, JSON.stringify(value))
    } catch (error) {
      console.error('Failed to set storage:', error)
    }
  }
  
  /**
   * 获取本地存储
   */
  static getItem(key, defaultValue) {
    try {
      const value = wx.getStorageSync(key)
      return value ? JSON.parse(value) : defaultValue || null
    } catch (error) {
      console.error('Failed to get storage:', error)
      return defaultValue || null
    }
  }
  
  /**
   * 移除本地存储
   */
  static removeItem(key) {
    try {
      wx.removeStorageSync(key)
    } catch (error) {
      console.error('Failed to remove storage:', error)
    }
  }
  
  /**
   * 清空本地存储
   */
  static clear() {
    try {
      wx.clearStorageSync()
    } catch (error) {
      console.error('Failed to clear storage:', error)
    }
  }
  
  /**
   * 获取存储信息
   */
  static getStorageInfo() {
    return wx.getStorageInfoSync()
  }
}

/**
 * 验证工具类
 */
class ValidationUtils {
  /**
   * 验证邮箱
   */
  static isEmail(email) {
    const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
    return regex.test(email)
  }
  
  /**
   * 验证手机号
   */
  static isPhone(phone) {
    const regex = /^1[3-9]\d{9}$/
    return regex.test(phone)
  }
  
  /**
   * 验证身份证号
   */
  static isIdCard(idCard) {
    const regex = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/
    return regex.test(idCard)
  }
  
  /**
   * 验证URL
   */
  static isUrl(url) {
    const regex = /^https?:\/\/.+/
    return regex.test(url)
  }
  
  /**
   * 验证密码强度
   */
  static getPasswordStrength(password) {
    let score = 0
    
    // 长度
    if (password.length >= 8) score++
    if (password.length >= 12) score++
    
    // 包含小写字母
    if (/[a-z]/.test(password)) score++
    
    // 包含大写字母
    if (/[A-Z]/.test(password)) score++
    
    // 包含数字
    if (/\d/.test(password)) score++
    
    // 包含特殊字符
    if (/[^\w\s]/.test(password)) score++
    
    if (score < 3) return 'weak'
    if (score < 5) return 'medium'
    return 'strong'
  }
}

/**
 * 设备工具类
 */
class DeviceUtils {
  /**
   * 获取系统信息
   */
  static getSystemInfo() {
    return wx.getSystemInfoSync()
  }
  
  /**
   * 判断是否为iOS
   */
  static isIOS() {
    const system = this.getSystemInfo().system
    return system.toLowerCase().includes('ios')
  }
  
  /**
   * 判断是否为Android
   */
  static isAndroid() {
    const system = this.getSystemInfo().system
    return system.toLowerCase().includes('android')
  }
  
  /**
   * 获取屏幕尺寸
   */
  static getScreenSize() {
    const info = this.getSystemInfo()
    return {
      width: info.screenWidth,
      height: info.screenHeight
    }
  }
  
  /**
   * 获取状态栏高度
   */
  static getStatusBarHeight() {
    return this.getSystemInfo().statusBarHeight || 0
  }
  
  /**
   * 获取导航栏高度
   */
  static getNavigationBarHeight() {
    const info = this.getSystemInfo()
    const menuButton = wx.getMenuButtonBoundingClientRect()
    return menuButton.top + menuButton.height + (menuButton.top - (info.statusBarHeight || 0))
  }
  
  /**
   * 获取安全区域
   */
  static getSafeArea() {
    return this.getSystemInfo().safeArea || {
      left: 0,
      right: 0,
      top: 0,
      bottom: 0,
      width: 0,
      height: 0
    }
  }
}

/**
 * 动画工具类
 */
class AnimationUtils {
  /**
   * 缓动函数
   */
  static easing = {
    linear: (t) => t,
    easeInQuad: (t) => t * t,
    easeOutQuad: (t) => t * (2 - t),
    easeInOutQuad: (t) => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t,
    easeInCubic: (t) => t * t * t,
    easeOutCubic: (t) => (--t) * t * t + 1,
    easeInOutCubic: (t) => t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1
  }
  
  /**
   * 创建动画
   */
  static createAnimation(duration = 400, timingFunction = 'ease') {
    return wx.createAnimation({
      duration,
      timingFunction: timingFunction
    })
  }
  
  /**
   * 延迟执行
   */
  static delay(ms) {
    return new Promise(resolve => setTimeout(resolve, ms))
  }
  
  /**
   * 节流
   */
  static throttle(func, wait) {
    let timeout = null
    let previous = 0
    
    return ((...args) => {
      const now = Date.now()
      const remaining = wait - (now - previous)
      
      if (remaining <= 0 || remaining > wait) {
        if (timeout) {
          clearTimeout(timeout)
          timeout = null
        }
        previous = now
        func.apply(null, args)
      } else if (!timeout) {
        timeout = setTimeout(() => {
          previous = Date.now()
          timeout = null
          func.apply(null, args)
        }, remaining)
      }
    })
  }
  
  /**
   * 防抖
   */
  static debounce(func, wait) {
    let timeout = null
    
    return ((...args) => {
      if (timeout) {
        clearTimeout(timeout)
      }
      timeout = setTimeout(() => {
        func.apply(null, args)
      }, wait)
    })
  }
}

/**
 * 图片工具类
 */
class ImageUtils {
  /**
   * 压缩图片
   */
  static compressImage(src, quality = 0.8) {
    return new Promise((resolve, reject) => {
      wx.compressImage({
        src,
        quality,
        success: (res) => resolve(res.tempFilePath),
        fail: reject
      })
    })
  }
  
  /**
   * 获取图片信息
   */
  static getImageInfo(src) {
    return new Promise((resolve, reject) => {
      wx.getImageInfo({
        src,
        success: resolve,
        fail: reject
      })
    })
  }
  
  /**
   * 保存图片到相册
   */
  static saveImageToPhotosAlbum(filePath) {
    return new Promise((resolve, reject) => {
      wx.saveImageToPhotosAlbum({
        filePath,
        success: () => resolve(),
        fail: reject
      })
    })
  }
  
  /**
   * 选择图片
   */
  static chooseImage(count = 1, sourceType = ['album', 'camera']) {
    return new Promise((resolve, reject) => {
      wx.chooseImage({
        count,
        sourceType,
        success: (res) => resolve(res.tempFilePaths),
        fail: reject
      })
    })
  }
}

// 导出所有工具类
module.exports = {
  TimeUtils,
  StringUtils,
  NumberUtils,
  ColorUtils,
  StorageUtils,
  ValidationUtils,
  DeviceUtils,
  AnimationUtils,
  ImageUtils
}